package com.hrt.datasender.process.strategy;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import com.btcode.common.MyLog;
import com.btcode.log.ILog;
import com.btcode.reflect.AutoClassLoader;
import com.btcode.reflect.IClassFinder;
import com.btcode.reflect.IClassLoader;
import com.hrt.datasender.datadao.model.BcSendPlatformDataStrategyModel;
import com.hrt.datasender.datadao.model.BcSendPlatformModel;
import com.hrt.datasender.datadao.service.BcSendPlatformDataStrategyService;
import com.hrt.datasender.datadao.service.BcSendPlatformService;

public final class ProcessStrategyLoader {

    private String basePacket = "com.hrt.datasender.process.strategy";

    private ILog log;

    private static volatile ProcessStrategyLoader instance;

    /**
     * 程序中存在的策略
     */
    private List<IProcessStrategy> existStrategys = new ArrayList<>();

    private HashMap<String, IProcessStrategy> platformStrategyMap = new HashMap<>();

    private HashMap<String, IProcessStrategy> commandStrategyMap = new HashMap<>();

    private ProcessStrategyLoader() {
        log = MyLog.getInstance().getLogger(getClass().getName());
    }

    public static ProcessStrategyLoader getInstance() {
        if (instance == null) {
            synchronized (ProcessStrategyLoader.class) {
                if (instance == null) {
                    instance = new ProcessStrategyLoader();
                }
            }
        }
        return instance;
    }

    public IProcessStrategy getStrategyByCommandId(String platformId, String commandId)
            throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException {
        loadAndGetStrategy();

        IProcessStrategy strategy = commandStrategyMap.get(platformId + "_" + commandId);

        return strategy;
    }

    public IProcessStrategy getStrategyById(String platformId, String strategyId)
            throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException {

        loadAndGetStrategy();

        IProcessStrategy strategy = platformStrategyMap.get(platformId + "_" + strategyId);

        return strategy;
    }

    /**
     * 加载配置好的策略
     * 
     * @throws IOException
     * @throws IllegalAccessException
     * @throws InstantiationException
     * @throws ClassNotFoundException
     * @throws MessageException
     */
    public synchronized void loadAndGetStrategy()
            throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException {

        if (!platformStrategyMap.isEmpty() && !commandStrategyMap.isEmpty()) {
            return;
        }

        platformStrategyMap = new HashMap<>();
        commandStrategyMap = new HashMap<>();

        List<IProcessStrategy> existStrategys = getExistStrategy();

        List<BcSendPlatformModel> bcSendPlatformModels = BcSendPlatformService.getInstance().getModelList();

        for (BcSendPlatformModel platform : bcSendPlatformModels) {

            String platformId = platform.getPlatformId();

            List<BcSendPlatformDataStrategyModel> bcSendPlatformDataStrategyModels = BcSendPlatformDataStrategyService
                    .getInstance().getList(platformId);

            for (BcSendPlatformDataStrategyModel strategyModel : bcSendPlatformDataStrategyModels) {

                String processStrategyId = strategyModel.getProcessStrategyId();

                for (IProcessStrategy strategy : existStrategys) {

                    if (strategy.getStrategyId().equals(processStrategyId)) {

                        IProcessStrategy processStrategy = strategy.getClass().newInstance();
                        String commandId = processStrategy.getCommandId();

                        platformStrategyMap.put(platformId + "_" + processStrategyId, processStrategy);
                        commandStrategyMap.put(platformId + "_" + commandId, processStrategy);
                        log.info("策略：" + basePacket + "." + processStrategyId + "已加载");
                    }
                }

            }

        }
    }

    /**
     * 获取系统中存在的策略
     * 
     * @param packetName
     * @return
     * @throws IOException
     * @throws ClassNotFoundException
     * @throws InstantiationException
     * @throws IllegalAccessException
     */
    public synchronized List<IProcessStrategy> getExistStrategy()
            throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {

        if (existStrategys != null && existStrategys.size() > 0) {
            return existStrategys;
        }

        IClassFinder strategyFinder = new ProcessStrategyClassFinder();
        IClassLoader calssLoader = new AutoClassLoader(strategyFinder);

        List<IProcessStrategy> strategyList = new ArrayList<>();
        List<Class<?>> strategyClasses = calssLoader.loadClass(getClass(), basePacket);

        for (Class<?> myClass : strategyClasses) {
            Object instance = myClass.newInstance();
            strategyList.add((IProcessStrategy) instance);
        }

        existStrategys = strategyList;

        return strategyList;
    }

}
